package stat;

import java.util.EnumMap;

public abstract class DerivedStat extends Stat implements StatNotifiable {

	private int cachedValue;
    private EnumMap<StatType, Integer> cache;
    private boolean shouldDerive;
    
    /**
     * constructor
     * @param st
     * @param toCache
     */
    public DerivedStat( StatType st, Stat... toCache) {
        super(st);
        cache = new EnumMap<StatType, Integer>(StatType.class);
        for(Stat s : toCache) {
            putInCache(s.getType(), s.getValue());
            s.register(this);
        }
        shouldDerive = toCache.length > 0;
    }
    
    /**
     * constructor
     * @param st
     * @param value
     * @param toCache
     */
    public DerivedStat( StatType st, int value, Stat... toCache) {
        super(st, value);
        cache = new EnumMap<StatType, Integer>(StatType.class);
        for(Stat s : toCache) {
            putInCache(s.getType(), s.getValue());
            s.register(this);
        }
        shouldDerive = toCache.length > 0;
    }
    
    /**
     * to be called when an observable updates
     */
    protected abstract void compute();
    
    /**
     * to see if the current derivedstat should derive
     * @return
     */
    public boolean shouldDerive() {
        return shouldDerive;
    }
    
    /**
     * compute the new value if observing
     */
    public void derive(StatType type, int value) {
        if(shouldDerive()) {
            putInCache(type, value);
            compute();
        }
    }
    
    /**
     * put the updated value into the cache
     * @param type
     * @param value
     */
    protected void putInCache(StatType type, int value ) {
        cache.put(type, value);
    }
    
    /**
     * get value of stat from cache
     * @param type
     * @return
     */
    protected int getFromCache(StatType type) {
        return cache.get(type);
    }
}
